/**
 * 通过 src/lib 目录下的 .js 生成函数 md 文档
 * 该文档用于文档快速查找
 */
const fs = require('fs')
const path = require('path')
const { Collect, CodeBlock } = require('./common')
const srcPath = path.resolve(__dirname, '../../src/lib')

/**
 * 解析函数体
 * @param {number} start 起始位置
 * @param {string} str 解析的字符串
 * @returns
 */
function parseFunctionCode(start, str) {
  let funcContent = ''
  let endIndex = start
  const name = new Collect('', '(')
  const params = new Collect('(', ')')
  const block = new CodeBlock('{', '}')
  for (let i = start, len = str.length; i < len; i++) {
    let s = str[i]
    funcContent += s
    // 函数名收集
    name.push(s)
    // 函数参数收集
    params.push(s)
    if (!params.done) {
      continue
    }
    // 函数体结束判断
    block.push(s)
    if (block.done) {
      endIndex = i
      break
    }
  }
  return { name: name.code, funcContent, endIndex }
}

/**
 * 解析文件
 * @param {string} str 文件字符
 * @returns
 */
function parseFile(str) {
  const func = new Collect('', 'function ')
  let funcList = []
  for (let i = 0, len = str.length; i < len; i++) {
    const s = str[i]
    func.push(s)
    if (func.done) {
      let { name, funcContent, endIndex } = parseFunctionCode(i, str)
      funcList.push({ name, code: func.code + funcContent })
      func.init()
      i = endIndex + 1
    }
  }
  return funcList
}

function main() {
  let fileList = fs.readdirSync(srcPath)
  let fileMdStr = []
  for (fileName of fileList) {
    if (!fileName.endsWith('.js') || fileName == 'index.js') {
      continue
    }
    let filePath = path.join(srcPath, fileName)
    let str = fs.readFileSync(filePath).toString()
    let funcList = parseFile(str)
    fileMdStr.push({ fileName, funcList })
  }
  let result = fileMdStr.reduce((p, c) => {
    let fnCodeStr = c.funcList.reduce((sp, sc) => {
      sp += `\n##${sc.name}\n\n` + '```js\n' + sc.code + '\n```'
      return sp
    }, '')
    p += `\n# ${c.fileName}\n\n${fnCodeStr}`
    return p
  }, `[toc]\n`)
  fs.writeFileSync(path.resolve(__dirname, './jcore-function-all.md'), result)
}

main()
